﻿#pragma once
#include "Singleton.h"
#include "GlobalVars.h"
#include "Color.h"
#include "Menu.h"
#include "Memory.h"
#include "Player.h"
#include "Config.h"

// 摄像机矩阵
struct view_matrix_t
{
	float matrix[4][4];

	float * operator[](int index)
	{
		return matrix[index];
	}
};

// 人物坐标矩阵
struct transform_matrix_t
{
	float matrix[3][4];

	float * operator[](int index)
	{
		return matrix[index];
	}
};

// 人物transform
struct FTransform
{
	Vector4 rotation;
	Vector3 translation;
	Vector3 scale3D;
};

// DX9的D3DXMATRIX，自己定义一个来用
struct MyD3DXMATRIX
{
public:
	float _11;
	float _12;
	float _13;
	float _14;

	float _21;
	float _22;
	float _23;
	float _24;

	float _31;
	float _32;
	float _33;
	float _34;

	float _41;
	float _42;
	float _43;
	float _44;

	void matrixMultiply(MyD3DXMATRIX & out, const MyD3DXMATRIX & other)
	{
		out._11 = this->_11 * other._11 + this->_12 * other._21 + this->_13 * other._31 + this->_14 * other._41;
		out._12 = this->_11 * other._12 + this->_12 * other._22 + this->_13 * other._32 + this->_14 * other._42;
		out._13 = this->_11 * other._13 + this->_12 * other._23 + this->_13 * other._33 + this->_14 * other._43;
		out._14 = this->_11 * other._14 + this->_12 * other._24 + this->_13 * other._34 + this->_14 * other._44;
		out._21 = this->_21 * other._11 + this->_22 * other._21 + this->_23 * other._31 + this->_24 * other._41;
		out._22 = this->_21 * other._12 + this->_22 * other._22 + this->_23 * other._32 + this->_24 * other._42;
		out._23 = this->_21 * other._13 + this->_22 * other._23 + this->_23 * other._33 + this->_24 * other._43;
		out._24 = this->_21 * other._14 + this->_22 * other._24 + this->_23 * other._34 + this->_24 * other._44;
		out._31 = this->_31 * other._11 + this->_32 * other._21 + this->_33 * other._31 + this->_34 * other._41;
		out._32 = this->_31 * other._12 + this->_32 * other._22 + this->_33 * other._32 + this->_34 * other._42;
		out._33 = this->_31 * other._13 + this->_32 * other._23 + this->_33 * other._33 + this->_34 * other._43;
		out._34 = this->_31 * other._14 + this->_32 * other._24 + this->_33 * other._34 + this->_34 * other._44;
		out._41 = this->_41 * other._11 + this->_42 * other._21 + this->_43 * other._31 + this->_44 * other._41;
		out._42 = this->_41 * other._12 + this->_42 * other._22 + this->_43 * other._32 + this->_44 * other._42;
		out._43 = this->_41 * other._13 + this->_42 * other._23 + this->_43 * other._33 + this->_44 * other._43;
		out._44 = this->_41 * other._14 + this->_42 * other._24 + this->_43 * other._34 + this->_44 * other._44;
	}
};

// 骨骼数据
struct BoneData
{
	Vector2 head; // 头
	Vector2 neck; // 脖子
	Vector2 chest; // 胸部
	Vector2 leftShoulder; // 左肩
	Vector2 rightShoulder; // 右肩
	Vector2 leftElbow; // 左手肘
	Vector2 rightElbow; // 右手肘
	Vector2 leftWrist; // 左手腕
	Vector2 rightWrist; // 右手腕
	Vector2 pelvis; // 盆骨
	Vector2 leftThigh; // 左大腿
	Vector2 rightThigh; // 右大腿
	Vector2 leftKnee; // 左膝盖
	Vector2 rightKnee; // 右膝盖
	Vector2 leftAnkle; // 左脚腕
	Vector2 rightAnkle; // 右脚腕
};

class Renderer : public Singleton <Renderer>
{
public:
	~Renderer()
	{
	};
	void increaseSpeed();

	void imDrawInit();
	void drawFrames();

	void drawImText(const Vector2 & pos, const char * text, Color color, bool outline = false, float fontSize = 15.0f);
	void drawImLine(const Vector2 & p1, const Vector2 & p2, Color color, float thickness = 1.0f);
	void drawImCircle(const Vector2 & center, float radius, int numSegments, Color color, float thickness = 1.0f);
	void drawImRect(const Vector2 & pos, const Vector2 & size, Color color, float thickness = 1.0f);
	void drawImCircleFilled(const Vector2 & center, float radius, int numSegments, Color color);
	void drawImRectFilled(const Vector2 & pos, const Vector2 & size, Color color);

	ImU32 GetU32(Color _color)
	{
		return ((_color[3] & 0xff) << 24) + ((_color[2] & 0xff) << 16) + ((_color[1] & 0xff) << 8) + (_color[0] & 0xff);
	}

	// 绘制线条宽度
	const float thickness = 1.0f;
	// 绘制文字字体大小
	const int fontSize = 20;

	//dx11驱动
	ID3D11Device * pD3DDevice = nullptr;
	//dx11上下文
	ID3D11DeviceContext * pD3DDeviceContext = nullptr;
	//dx交换链
	IDXGISwapChain * pSwapChain = nullptr;
	ID3D11RenderTargetView * pMainRenderTargetView = nullptr;

	ImDrawList * pImBuffer = nullptr;
private:
	void lockHp();
	void noRecoil();
	bool transformCoord(shared_ptr<Player> player, view_matrix_t matrix);
	bool playerWorldToScreen(const Vector2 & screen_size, const Vector3 & pos, Box & box, view_matrix_t matrix);
	void boxEsp(shared_ptr<Player> player);
	void lineEsp(shared_ptr<Player> player);
	void hpEsp(shared_ptr<Player> player);
	void distanceEsp(shared_ptr<Player> player);
	void drawMenu();

	void aimbot(shared_ptr<Player> player, view_matrix_t matrix);
	void drawTest(shared_ptr<Player> player, view_matrix_t matrix, Color color);
	void drawMatchstickMen(shared_ptr<Player> player, view_matrix_t matrix, Color color);
	bool aimbootWorldToScreen(const Vector2 & screen_size, const Vector3 & pos, Vector2 & retPos, view_matrix_t matrix);
	Vector3 getBonePos(uintptr_t skeletonMatrixAddr, uintptr_t boneAddr);
	bool boneWorldToScreen(const Vector2 & screen_size, const Vector3 & pos, Vector2 & retPos, view_matrix_t matrix);
	void readTransform(FTransform & out, uintptr_t addr);
	void toMatrixWithScale(MyD3DXMATRIX & out, Vector4 rotation, Vector3 translation, Vector3 scale3D);

	struct vertex
	{
		float x, y, z, rhw;
		D3DCOLOR color;
	};

	// 自瞄锁定目标
	shared_ptr<Player> lockAimTarget = nullptr;
	// 优化点按瞄准镜切换
	int aimCounter = 0;
};
